import React, { useState, useEffect, useRef } from 'react'
import styles from './index.module.less'
import { getUId, throttle } from '../../utils/tool'
import { cloneDeep } from 'lodash'
import classNames from 'classnames'
import { useGetLineInfo } from '../drag/test'

const isEmptyObject = (obj) => {
	if (typeof obj !== 'object') return false
	const keys = Reflect.ownKeys(obj)
	return !keys.length
}

const initList = [
	{ label: 'child1', uuid: getUId(), top: 20, left: 20 },
	{ label: 'child2', uuid: getUId(), top: 90, left: 20 },
	{ label: 'child3', uuid: getUId(), top: 190, left: 20 },
	{ label: 'child4', uuid: getUId(), top: 80, left: 120 },
	{ label: 'child5', uuid: getUId(), top: 160, left: 220 },
	{ label: 'child6', uuid: getUId(), top: 120, left: 320 },
	{ label: 'child7', uuid: getUId(), top: 220, left: 420 },
	{ label: 'child8', uuid: getUId(), top: 120, left: 494 },
	{ label: 'child9', uuid: getUId(), top: 439, left: 820 },
	{ label: 'child10', uuid: getUId(), top: 554, left: 633 },
	{ label: 'child11', uuid: getUId(), top: 448, left: 808 },
	{ label: 'child12', uuid: getUId(), top: 80, left: 808 },
	{ label: 'child13', uuid: getUId(), top: 129, left: 611 },
	{ label: 'child14', uuid: getUId(), top: 294, left: 106 },
	{ label: 'child15', uuid: getUId(), top: 477, left: 321 },
	{ label: 'child16', uuid: getUId(), top: 149, left: 274 },
	{ label: 'child17', uuid: getUId(), top: 189, left: 418 },
	{ label: 'child18', uuid: getUId(), top: 54, left: 41 },
	{ label: 'child19', uuid: getUId(), top: 67, left: 115 },
	{ label: 'child20', uuid: getUId(), top: 395, left: 19 },
	{ label: 'child21', uuid: getUId(), top: 563, left: 452 },
	{ label: 'child22', uuid: getUId(), top: 537, left: 413 },
	{ label: 'child23', uuid: getUId(), top: 494, left: 265 },
	{ label: 'child24', uuid: getUId(), top: 317, left: 211 },
	{ label: 'child25', uuid: getUId(), top: 224, left: 156 },
	{ label: 'child26', uuid: getUId(), top: 276, left: 54 },
	{ label: 'child27', uuid: getUId(), top: 467, left: 165 },
	{ label: 'child28', uuid: getUId(), top: 268, left: 315 },
	{ label: 'child29', uuid: getUId(), top: 335, left: 107 },
	{ label: 'child30', uuid: getUId(), top: 336, left: 518 },
	{ label: 'child31', uuid: getUId(), top: 578, left: 208 },
	{ label: 'child32', uuid: getUId(), top: 147, left: 455 },
	{ label: 'child33', uuid: getUId(), top: 75, left: 488 },
	{ label: 'child34', uuid: getUId(), top: 392, left: 292 },
	{ label: 'child35', uuid: getUId(), top: 397, left: 452 },
	{ label: 'child36', uuid: getUId(), top: 384, left: 156 },
	{ label: 'child37', uuid: getUId(), top: 242, left: 536 },
	{ label: 'child38', uuid: getUId(), top: 255, left: 231 },
	{ label: 'child39', uuid: getUId(), top: 325, left: 4404 },
	{ label: 'child40', uuid: getUId(), top: 329, left: 630 },
	{ label: 'child41', uuid: getUId(), top: 143, left: 572 },
]

const Demo = () => {
	const containerRef = useRef()
	const leftLineRef = useRef()
	const topLineRef = useRef()

	const [curSelectNode, setCurSelectNode] = useState({})
	const [curSelectNodeIdx, setCurSelectNodeIdx] = useState(undefined)

	const [startX, setStartX] = useState(undefined)
	const [startY, setStartY] = useState(undefined)

	const [initNodeX, setInitNodeX] = useState(undefined)
	const [initNodeY, setInitNodeY] = useState(undefined)

	const [initLineTop, setInitLineTop] = useState(0)
	const [initLineLeft, setInitLineLeft] = useState(0)

	const [lineShow, setLineShow] = useState(false)

	const [lineLeftNums, setLineLeftNums] = useState([])
	const [lineLeftMidNums, setLineLeftMidNums] = useState([])
	const [lineRightNums, setLineRightNums] = useState([])
	const [lineTopNums, setLineTopNums] = useState([])
	const [lineTopMidNums, setLineTopMidNums] = useState([])
	const [lineBtmNums, setLineBtmNums] = useState([])

	const [moveX, setMoveX] = useState(0)
	const [moveY, setMoveY] = useState(0)

	// const {lineTop, lineLeft, tFlag, lFlag} = useGetLineInfo(
	// 	moveX,
	// 	moveY,
	// 	curSelectNode,
	// 	lineLeftNums,
	// 	lineLeftMidNums,
	// 	lineRightNums,
	// 	lineTopNums,
	// 	lineTopMidNums,
	// 	lineBtmNums
	// )

	const [list, setList] = useState(initList)

	useEffect(() => {
		const nodes = Array.from(containerRef.current.childNodes).slice(2)
		const newDataList = cloneDeep(list)
		nodes.forEach((item, idx) => {
			newDataList[idx].width = item.clientWidth
			newDataList[idx].height = item.clientHeight
		})
		setCurSelectNode(newDataList[curSelectNodeIdx])
		let leftNums = []
		let leftMidNums = []
		let rightNums = []
		let topNums = []
		let topMidNums = []
		let btmNums = []
		const flag = newDataList.every((item, idx) => {
			leftNums.push(item.left)
			leftMidNums.push(item.left + item.width / 2)
			rightNums.push(item.left + item.width)
			topNums.push(item.top)
			topMidNums.push(item.top + item.height / 2)
			btmNums.push(item.top + item.height)
			return item.height === list[idx].height && item.width === list[idx].width
		})
		setLineLeftNums(Array.from(new Set(leftNums)))
		setLineLeftMidNums(Array.from(new Set(leftMidNums)))
		setLineRightNums(Array.from(new Set(rightNums)))
		setLineTopNums(Array.from(new Set(topNums)))
		setLineTopMidNums(Array.from(new Set(topMidNums)))
		setLineBtmNums(Array.from(new Set(btmNums)))
		!flag && setList(newDataList)
	}, [list, curSelectNodeIdx])

	const onMouseDown = (event, target, idx) => {
		setLineShow(true)
		setStartX(event.pageX)
		setStartY(event.pageY)
		setCurSelectNodeIdx(idx)
		setInitNodeX(target.left)
		setInitNodeY(target.top)
		setCurSelectNode({ ...target })
	}

	const getLineInfo = (tY, tX, node) => {
		const cTop = tY
		const cMidT = tY + node.clientHeight / 2
		const cBtm = tY + node.clientHeight
		const cLeft = tX
		const cMidW = tX + node.clientWidth / 2
		const cRight = tX + node.clientWidth

		let lineTop = 0,
			lineLeft = 0

		let topFlag = [cMidT, cTop, cBtm].some((item) => {
			let flag = false
			if (lineTopMidNums.includes(item) || lineTopNums.includes(item) || lineBtmNums.includes(item)) {
				lineTop = item
				return true
			}
			return flag
		})

		let leftFlag = [cMidW, cLeft, cRight].some((item) => {
			let flag = false
			if (lineLeftMidNums.includes(item) || lineLeftNums.includes(item) || lineRightNums.includes(item)) {
				lineLeft = item
				return true
			}
			return flag
		})

		return { lineTop, lineLeft, topFlag, leftFlag }
	}

	const mouseMove = (event) => {
		if (isEmptyObject(curSelectNode)) return

		const moveX = event.pageX - startX
		const moveY = event.pageY - startY
		setMoveX(moveX)
		setMoveY(moveY)
		const node = getNode()
		if (node) {
			const tY = initNodeY + moveY
			const tX = initNodeX + moveX
			node.style.top = tY + 'px'
			node.style.left = tX + 'px'

			const { lineTop, lineLeft, topFlag, leftFlag } = getLineInfo(tY, tX, node)
			topLineRef.current.style.transform = `translateY(${lineTop}px)`
			leftLineRef.current.style.transform = `translateX(${lineLeft}px)`

			topLineRef.current.style.display = topFlag ? 'block' : 'none'
			leftLineRef.current.style.display = leftFlag ? 'block' : 'none'
		}
	}

	const mouseUp = () => {
		setLineShow(false)
		if (isEmptyObject(curSelectNode)) return
		setCurSelectNode({})
		const node = getNode()
		if (curSelectNode) {
			curSelectNode.top = +node.style.top.replace('px', '')
			curSelectNode.left = +node.style.left.replace('px', '')
		}
		setList((list) => {
			list[curSelectNodeIdx] = { ...curSelectNode }
			return list
		})
	}

	const getNode = () => {
		const nodes = Array.from(containerRef.current.childNodes).slice(2)
		return nodes[curSelectNodeIdx]
	}

	return (
		<div
			onMouseMove={async (event) => {
				await event.persist()
				mouseMove(event)
			}}
			onMouseUp={mouseUp}
			className={styles.moveBox}
			ref={containerRef}
		>
			<div
				className={classNames(
					styles.leftLine
					// lineShow && lFlag && styles.lineShow
				)}
				ref={leftLineRef}
				// style={{transform: `translateX(${lineLeft}px)`}}
			/>
			<div
				className={classNames(
					styles.topLine
					// lineShow && tFlag && styles.lineShow
				)}
				ref={topLineRef}
				// style={{transform: `translateY(${lineTop}px)`}}
			/>
			{list.map((item, idx) => {
				return (
					<div
						className={styles.child}
						key={item.uuid}
						onMouseDown={(event) => onMouseDown(event, item, idx)}
						style={{ top: item.top, left: item.left }}
					>
						{item.uuid.slice(0, 5)}
					</div>
				)
			})}
		</div>
	)
}

export default Demo
